<?php

namespace Plugins\AdminBasic\Http\Admin\Service\MakeCURDFiles;

use App\Requests\AbstractRequest;
use Hyperf\Stringable\Str;
use Hyperf\Validation\Rule;
use Sc\Util\ClassFile\Components\ClassFileConstruction;
use Sc\Util\ClassFile\Components\Method;
use Sc\Util\ClassFile\Components\Out\ValueOut;

/**
 * Class MakeRequest
 */
class MakeRequest extends AbstractMake
{

    public function make(): string
    {
        $request = new ClassFileConstruction(Str::studly($this->table) . 'Request');
        $request->setNamespace($this->getNamespace('Requests'));
        $request->addUses(AbstractRequest::class);
        $request->addUses(Rule::class);
        $request->setExtends(AbstractRequest::class);

        $request->setDocBlock($this->tableComment . '验证器');

        $this->addMethodAllRules($request);
        $this->addMethodAttributes($request);
        $this->addMethodUpdateScene($request);
        $this->addMethodStoreScene($request);
        $this->addMethodDestroyScene($request);

        return $this->makeFile($this->getFilename('FormRequest'), $request->out());
    }
    private function addMethodAllRules(ClassFileConstruction $request): void
    {
        $validateFields = array_filter($this->fields, fn($v) => !empty($v['form_type']));

        $method = new Method('allRules');
        $method->setReturnType('array');

        $rules     = ['id' => ['required']];
        foreach ($validateFields as $field) {
            $rules[$field['field']] = ['required'];
        }

        $method->addCode("return " . ValueOut::out($rules, 8) . ';');

        $request->addMethods($method);
    }

    private function addMethodAttributes(ClassFileConstruction $request): void
    {
        $validateFields = array_filter($this->fields, fn($v) => !empty($v['form_type']));

        $method = new Method('attributes');
        $method->setReturnType('array');

        $rules     = [];
        foreach ($validateFields as $field) {
            $rules[$field['field']] = $field['comment'];
        }

        $method->addCode("return " . ValueOut::out($rules, 8) . ';');

        $request->addMethods($method);
    }

    private function addMethodStoreScene(ClassFileConstruction $request): void
    {
        $validateFields = array_filter($this->fields, fn($v) => !empty($v['form_type']));

        $method = new Method('storeScene');
        $method->setReturnType('array');

        $fields = array_column($validateFields, 'field');
        $fields = array_values(array_diff($fields, ['id']));

        $method->addCode("return " . ValueOut::out($fields, 8) . ';');

        $request->addMethods($method);
    }

    private function addMethodUpdateScene(ClassFileConstruction $request): void
    {
        $validateFields = array_filter($this->fields, fn($v) => !empty($v['form_type']));

        $method = new Method('updateScene');
        $method->setReturnType('array');

        $fields = array_column($validateFields, 'field');

        $method->addCode("return " . ValueOut::out($fields, 8) . ';');

        $request->addMethods($method);
    }

    private function addMethodDestroyScene(ClassFileConstruction $request): void
    {
        $method = new Method('destroyScene');
        $method->setReturnType('array');

        $method->addCode("return " . ValueOut::out(['data' => 'array'], 8) . ';');

        $request->addMethods($method);
    }



}